package cn.edu.zjut.mina.service.impl;

import java.net.InetSocketAddress;
import java.util.List;

import org.apache.mina.core.session.IoSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import cn.edu.zjut.mina.bean.RoomInfo;
import cn.edu.zjut.mina.bean.StandardFormat;
import cn.edu.zjut.mina.bean.UserSession;
import cn.edu.zjut.mina.interf.IRoomInfo;
import cn.edu.zjut.mina.po.UserInfo;
import cn.edu.zjut.mina.protocal.JMessageProtocalRes;
import cn.edu.zjut.mina.protocal.ProtocalRegulation;
import cn.edu.zjut.mina.repository.UserInfoRepository;
import cn.edu.zjut.mina.service.INotificationService;
import cn.edu.zjut.mina.service.IUserInitService;
import cn.edu.zjut.mina.util.DateUtils;
import cn.edu.zjut.mina.util.GsonUtils;
import cn.edu.zjut.mina.util.UserMap;
import cn.edu.zjut.mina.util.UserSessionMap;
import cn.edu.zjut.mina.util.ResultInfoConstUtils;

/**
 * 用户初始化
 * 
 * @author 张宇翔
 * 
 *         温从林（2-6）
 */

@Service("userInitService")
public class UserInitServiceImpl implements IUserInitService {

	@Autowired
	private UserInfoRepository userInfoRepository;

	@Qualifier("notificationService")
	@Autowired
	private INotificationService notificationService;

	/**
	 * 用于存放房间信息的集合
	 */
	private final UserSessionMap userSessionMap = UserSessionMap.getInstance();

	/**
	 * 用于存放用户信息的集合
	 */
	private final UserMap userMap = UserMap.getInstance();

	/**
	 * 用户信息初始化
	 */
	public JMessageProtocalRes init(StandardFormat inJson, IoSession session) {
		// TODO Auto-generated method stub
		System.out.println(DateUtils.getTime() + "用户" + session.getAttribute("user") + "execute --Init()-- method.");
		JMessageProtocalRes res = new JMessageProtocalRes();
		StandardFormat outJson = new StandardFormat();
		String datas;
		String clientIP = ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress();
		int newClientPort = ((InetSocketAddress) session.getRemoteAddress()).getPort();
		
		UserInfo user = null;
		if (userMap.get(inJson.userId) == null) {
			user = userInfoRepository.findByUserId(inJson.userId);
		} else {
			UserInfo userTemp = userInfoRepository.findByUserId(inJson.userId);
			/**
			 * 更新缓存中的用户信息(比如用户修改了昵称等，游戏中也需要修改)
			 */
			user = userMap.get(inJson.userId).user;
			String oldClientIP =user.getIp();
			
			
			user.setNickName(userTemp.getNickName());
			user.setRefresh_token(userTemp.getRefresh_token());
			user.setRefresh_token_time(userTemp.getRefresh_token_time());
			user.setExpires_in(userTemp.getExpires_in());
			user.setAccess_token_time(userTemp.getAccess_token_time());
			user.setAccess_token(userTemp.getAccess_token());
			user.setSex(userTemp.getSex());
			user.setProvince(userTemp.getProvince());
			user.setCity(userTemp.getCity());
			user.setCountry(userTemp.getCountry());
			user.setHeadimgurl(userTemp.getHeadimgurl());
			
			//异地登录比较ip
//			IoSession oldSession=userMap.get(inJson.userId).session;
//			System.out.println(user.getPort());
//			
//			System.out.println(newClientPort);
//			if(!oldClientIP.equals(clientIP) || user.getPort() != newClientPort){
//				outJson.resultInfo=ResultInfoConstUtils.REMOTE_LOGIN;
//				outJson.userId=user.getUserId();
//				res.setResultCode(ProtocalRegulation.REMOTELOGIN);
//				datas = GsonUtils.beanToJson(outJson).trim();
//				res.setContent(datas);
//				
//				if(oldSession != null){
//					System.out.println("发送异地登录消息:");
//					oldSession.write(res);
//				}
//			}
			
		}
		
		outJson = new StandardFormat();
		// 更新ip
		user.setIp(clientIP);
		user.setPort(newClientPort);
		UserSession userSession = new UserSession(user, session);
		// 添加或更新userMap
		userMap.put(inJson.userId, userSession);
		
		
		if (user.getLostConnection() != null && user.getLostConnection() == 1) {// 说明玩家
																				// 断线了
																				// 需要恢复数据
			// 设置断线状态为连接正常
			user.setLostConnection(0);

			// 用户首次登录，还没创建过房间
			if (user.getRoomId() == null) {
				outJson.userId = inJson.userId;
				outJson.result = false;
				outJson.resultInfo = ResultInfoConstUtils.USERINIT_ROOMNULLINFO;
			} else if (userSessionMap.get(user.getRoomId()) == null) {// 用户信息中有房间数据，但房间map中不存在该房间，说明房间已经解释了
				user.clear();// 清空玩家数据 考虑到玩家掉线然后房间被解散了(下个版本会用到，现在先加上)
				outJson.userId = inJson.userId;
				outJson.result = false;
				outJson.resultInfo = ResultInfoConstUtils.USERINIT_DISINFO;
			} else {// 断线重连，需要恢复数据
				// 根据房间号获取该房间内的所有用户session
				System.out.println(DateUtils.getTime() + "用户" + session.getAttribute("user") + "恢复房间内数据roomid=" + user.getRoomId());
				List<UserSession> userSessionList = userSessionMap.get(user.getRoomId()).getUserSessions();
				int i = 0;
				for (; i < userSessionList.size(); i++) {
					// 遍历session
					if (userSessionList.get(i).user.getUserId().equals(inJson.userId)) {
						userSessionList.get(i).session = session;// session替换
						break;
					}
				}
				// 房间在，但是已经被别人占用了，这种情况存在于房间解散后，又被别人创建
				if (i == userSessionList.size()) {
					
					user.clear();// 清空玩家数据 考虑到玩家掉线然后房间被解散了(下个版本会用到，现在先加上)
					outJson.userId = inJson.userId;
					outJson.result = false;
					outJson.resultInfo = ResultInfoConstUtils.USERINIT_ROOMOCCUPYINFO;
				} else {
					
					outJson.userId = inJson.userId;
					outJson.result = true;
					outJson.resultInfo = ResultInfoConstUtils.USERINIT_NORMALINFO;
					
					// 恢复玩家数据
//					notificationService.notificationRecover(userSessionMap.get(user.getRoomId()).getRoomId(),
//							inJson.userId);
//					// 重连后的res在notification中统一处理，这里只要返回null就行了
//					return null;
				}
			}
		}
		//若用户在房间内，则替换房间内与用户id相同的session
		else if(user.getLostConnection() != null && user.getLostConnection() == 0 && inJson.roomId!=null){
			
			IRoomInfo roomInfo = userSessionMap.get(inJson.roomId);
			
			if(roomInfo == null){
				
				outJson.userId = inJson.userId;
				outJson.result = false;
				outJson.resultInfo = ResultInfoConstUtils.RECOVER_ROOMNULLINFO;
				
				res.setResultCode(ProtocalRegulation.RECOVERINITIATIVE);
				datas = GsonUtils.beanToJson(outJson).trim();
				res.setContent(datas);
				return res;
			}
			
			List<UserSession> userSessionListP=  roomInfo.getUserSessions();
			
			for (int j=0; j < userSessionListP.size(); j++) {
				// 遍历session
				if (userSessionListP.get(j).user.getUserId().equals(inJson.userId)) {
					userSessionListP.get(j).session = session;// session替换
					break;
				}
			}
			notificationService.notificationRecoverInGame(userSessionMap.get(user.getRoomId()).getRoomId(),
					inJson.userId);
			return null;
		}
		else {// 不需要数据恢复
			outJson.userId = inJson.userId;
			outJson.result = true;
			outJson.resultInfo = ResultInfoConstUtils.USERINIT_NORMALINFO;
		}

		res.setResultCode(ProtocalRegulation.init);
		datas = GsonUtils.beanToJson(outJson).trim();
		res.setContent(datas);
		return res;
	}

}
